﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using UnityScriptEngine;
using StoreClientModule;
using System.Drawing.Printing;

namespace MBBStoreClient
{
    public partial class frmNewReceivable : Form
    {
        bool isViewAll = false;
        UnityProcessor proc = new UnityProcessor();
        Threader t = new Threader();
        UnityScript[] dat = new UnityScript[0];

        string filter = "";

        DataTable referenceNumbers = new DataTable();
        DataTable chargeInvoices = new DataTable();
        DataTable payments = new DataTable();
        DataTable profile = new DataTable();
        DataTable result = new DataTable();
        DataTable result02 = new DataTable();
        DataRow[] invoices = new DataRow[0];

        public frmNewReceivable()
        {
            InitializeComponent();
            InitializeFrameSliderForm();
        }

        private void InitializeForm()
        {
            txtFilter.SelectedIndex = 0;
            btnPrint.Click +=new EventHandler(btnPrint_Click);
            chkAsOf.Click += new EventHandler(chkAsOf_Click);
            proc.ProcessCompleted += new ProcessHandler(proc_ProcessCompleted);
            proc.ProcessError += new ProcessHandler(proc_ProcessError);
            btnSearch.Click += new EventHandler(btnSearch_Click);
            t.MethodCompleted += new EventHandler(t_MethodCompleted);
        }

        void t_MethodCompleted(object sender, EventArgs e)
        {
            t.SafeCall(this, delegate
            {
                switch (sender.ToString())
                {
                    case "ExtractResult":
                        switch (filter)
                        {
                            case "All": 
                                grdItems.DataSource = result;
                                lblStatus.Text = dat[0].Data_Count + " Results(s) @ " + proc.ProcEnd() + " sec.";
                                FormatGrid();
                                pnlMsg.Visible = false;
                                groupBox1.Enabled = true;
                                break;
                            case "With Balance": invoices = result.Select("[Total Balance] <> '0'");
                                t.MethodCall(generateFinalResult);
                                break;
                            case "Fully Paid": invoices = result.Select("[Total Balance] = '0'");
                                t.MethodCall(generateFinalResult);
                                break;
                        }
                        break;
                    case "generateFinalResult":
                        grdItems.DataSource = result02;
                        lblStatus.Text = result02.Rows.Count + " Results(s) @ " + proc.ProcEnd() + " sec.";
                        FormatGrid();

                        groupBox1.Enabled = true;
                        pnlMsg.Visible = false;
                        break;
                }
            });
        }

        void btnSearch_Click(object sender, EventArgs e)
        {
            pnlMsg.Visible = true;
            filter = txtFilter.Text;
            groupBox1.Enabled = false;
            Search();

        }

        void proc_ProcessError(string id, string desc)
        {
            t.SafeCall(this, delegate
            {
                MessageBox.Show(desc);
            });
        }

        void proc_ProcessCompleted(string id, string desc)
        {
            t.SafeCall(this, delegate
            {
                switch (id)
                {
                    case "SEARCH":
                        proc.DBPUX_Data_Fetch(out dat);

                        referenceNumbers = dat[0].ToDataTable();
                        chargeInvoices = dat[1].ToDataTable();
                        payments = dat[2].ToDataTable();
                        profile = dat[3].ToDataTable();

                        t.MethodCall(ExtractResult);

                        
                        break;
                }
            });
        }

        void chkAsOf_Click(object sender, EventArgs e)
        {
            if (chkAsOf.Checked == true)
            {
                MessageBox.Show("Please Select Date ... Note: All Records will be extracted");
                txtDateTo.Enabled = false;
                isViewAll = true;
            }
            else
            {
                txtDateTo.Enabled = true;
                isViewAll = false;
            }
        }

        //operations
        void Search()
        {
            while (proc.IsRunning)
            {

            }
            proc.ProcStart();
            UnityScript u = new UnityScript("SEARCH", 7);
            u.Script_Add(Script.DBPUX_BEGIN);
            u.Script_Add(Script.DBPUX_QUERY, string.Format("SELECT DISTINCT fRef FROM tblsalesdetail WHERE fInvoiceType = 'Charged'"));
            u.Script_Add(Script.DBPUX_QUERY, string.Format("SELECT fID, fDate, t1.fRef, t1.fInvoice, ffAmount , fStamp " +
                        "FROM tblsalesdetail t1, (SELECT SUM(fQty * fUnitPrice) AS ffAmount, t22.fInvoice FROM tblsalesitem t22 GROUP BY t22.fInvoice) AS t2 " +
                        "WHERE (fInvoiceType = 'Charged') AND (t1.fInvoice = t2.fInvoice)"));
            u.Script_Add(Script.DBPUX_QUERY, string.Format("SELECT fID, SUM(fAmount), fInvoiceNumber, fStamp FROM tblchargepayments GROUP BY fInvoiceNumber"));
            u.Script_Add(Script.DBPUX_QUERY, string.Format("SELECT fID, fRef, fSoldTo, fStamp FROM tblprofile WHERE fRef LIKE 'B%'"));
            u.Script_Add(Script.DBPUX_COMMIT);
            proc.Run(u);
        }
        void FormatGrid()
        {

            grdItems.Columns[0].Width = (grdItems.Width * 10) / 100;
            grdItems.Columns[1].Width = (grdItems.Width * 20) / 100;
            grdItems.Columns[2].Width = (grdItems.Width * 15) / 100;
            grdItems.Columns[3].Width = (grdItems.Width * 15) / 100;
            grdItems.Columns[4].Width = (grdItems.Width * 15) / 100;
            

            grdItems.Columns[0].DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleLeft;
            grdItems.Columns[1].DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleCenter;
            grdItems.Columns[2].DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleRight;
            grdItems.Columns[3].DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleRight;
            grdItems.Columns[4].DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleRight;
            
            if (grdItems.Rows.Count > 0)
            {
                for (int i = 0; i < grdItems.Rows.Count; i++)
                {
                    grdItems.Rows[i].Cells[2].Value = float.Parse(grdItems.Rows[i].Cells[2].Value.ToString()).ToString("#,#0.00");
                    grdItems.Rows[i].Cells[3].Value = float.Parse(grdItems.Rows[i].Cells[3].Value.ToString()).ToString("#,#0.00");
                    grdItems.Rows[i].Cells[4].Value = float.Parse(grdItems.Rows[i].Cells[4].Value.ToString()).ToString("#,#0.00");

                }
            }
        }
        void ExtractResult()
        {
            result = new DataTable();
            result.Columns.Add("RefNumber");
            result.Columns.Add("Account Name");
            result.Columns.Add("Total Charged");
            result.Columns.Add("Total Payment");
            result.Columns.Add("Total Balance");

            DataRow dr;

            for (int i = 0; i < referenceNumbers.Rows.Count; i++)
            {
                string refNum = referenceNumbers.Rows[i]["fRef"].ToString();
                dr = result.NewRow();
                dr["RefNumber"] = refNum;
                //account name
                for (int j = 0; j < profile.Rows.Count; j++)
                {
                    string refNumber = profile.Rows[j]["fRef"].ToString();
                    if (refNum.Equals(refNumber))
                    {
                        string accountName = profile.Rows[j]["fSoldTo"].ToString();
                        dr["Account Name"] = accountName;
                    }
                }
                //charge invoice
                string[] chargeInvoice = new string[0];

                DateTime startDate = txtDateFrom.Value;
                DateTime endDate = txtDateTo.Value;

                float gtCharge = 0.0f;
                for (int k = 0; k < chargeInvoices.Rows.Count; k++)
                {
                    string cRefNum = chargeInvoices.Rows[k]["fRef"].ToString();
                    string _chargeInvoice = chargeInvoices.Rows[k]["fInvoice"].ToString();
                    float amtC = float.Parse(chargeInvoices.Rows[k]["ffAmount"].ToString());
                    DateTime filterDate = DateTime.Parse(chargeInvoices.Rows[k]["fDate"].ToString());

                    if (refNum.Equals(cRefNum) && isViewAll == true && filterDate <= startDate)
                    {
                        Array.Resize<string>(ref chargeInvoice, chargeInvoice.Length + 1);
                        chargeInvoice[chargeInvoice.Length - 1] = _chargeInvoice;
                        gtCharge += amtC;
                    }
                    else if (refNum.Equals(cRefNum) && isViewAll == false && filterDate >= startDate && filterDate <= endDate)
                    {
                        Array.Resize<string>(ref chargeInvoice, chargeInvoice.Length + 1);
                        chargeInvoice[chargeInvoice.Length - 1] = _chargeInvoice;
                        gtCharge += amtC;
                    }
                }
                dr["Total Charged"] = gtCharge.ToString();

                //payments
                float gtPayment = 0.0f;
                for (int l = 0; l < chargeInvoice.Length; l++)
                {
                    for (int m = 0; m < payments.Rows.Count; m++)
                    {
                        string cInvoice = payments.Rows[m]["fInvoiceNumber"].ToString();
                        float amtP = float.Parse(payments.Rows[m][0].ToString());
                        if (chargeInvoice[l].Equals(cInvoice))
                        {
                            gtPayment += amtP;
                        }
                    }
                }
                dr["Total Payment"] = gtPayment.ToString();
                float gtBalance = gtCharge - gtPayment;
                dr["Total Balance"] = gtBalance.ToString();
                result.Rows.Add(dr);
            }
        }
        void generateFinalResult()
        {
            result02 = result.Clone();
            for (int i = 0; i < invoices.Length; i++)
                result02.ImportRow(invoices[i]);
        }
        //printing
        int cnt = 0;
        int pp = 1;
        int pageNum = 1;
        double gTC = 0, gTP = 0, gTB = 0;
        void btnPrint_Click(object sender, EventArgs e)
        {
            gTC = 0;
            gTP = 0;
            gTB = 0;
            if (grdItems.Rows.Count > 0)
            {
                PrintDocument pd = new PrintDocument();
                pd.DocumentName = lblText.Text;
                pd.PrintPage += new PrintPageEventHandler(pd_PrintPage);
                PrintDialog pdlg = new PrintDialog();
                pdlg.Document = pd;
                if (pdlg.ShowDialog() == DialogResult.OK)
                {
                    PrintPreviewDialog ppdlg = new PrintPreviewDialog();
                    ppdlg.Document = pd;
                    ppdlg.ShowDialog();
                }
            }
        }
        
        void pd_PrintPage(object sender, PrintPageEventArgs e)
        {
            float lpp = 0;
            float y = 0, y2 = 0, tmp = 0;
            float tm = e.MarginBounds.Top;
            float lm = e.MarginBounds.Left;
            float rm = e.PageBounds.Width - 100;
            float bm = e.PageBounds.Height - 100;
            float ht = 0;
            Font cFont;
            StringFormat sf = new StringFormat();
            float tmpStx = 0;

            //Header
            y = 150;
            y2 = 150;

            cFont = new Font("Courier New", 12f, FontStyle.Bold);
            ht = cFont.GetHeight(e.Graphics);
            sf.Alignment = StringAlignment.Center;
            e.Graphics.DrawString(Common.lStoreName, new Font("Courier New", 15f, FontStyle.Bold), Brushes.Black, e.PageBounds.Width / 2, 50, sf);

            sf.Alignment = StringAlignment.Center;
            e.Graphics.DrawString("STATEMENT OF ACCOUNT SUMMARY", new Font("Courier New", 15f, FontStyle.Bold), Brushes.Black, e.PageBounds.Width / 2, 90, sf);

            sf.Alignment = StringAlignment.Near;
            string str = "";
            e.Graphics.DrawString(str, cFont, Brushes.Black, lm, y, sf);

            sf.Alignment = StringAlignment.Far;
            if (isViewAll == false)
                e.Graphics.DrawString("From " + txtDateFrom.Text + " To " + txtDateTo.Text + " - Page - "+pageNum, cFont, Brushes.Black, rm, y, sf);
            else
                e.Graphics.DrawString("As Of " + txtDateFrom.Text + " - Page - " + pageNum, cFont, Brushes.Black, rm, y, sf);
            //Column Header
            y += ht;
            y2 += ht;

            e.Graphics.FillRectangle(Brushes.LightGray, lm, y, rm - lm, ht);
            e.Graphics.DrawRectangle(new Pen(Brushes.Black), lm, y, rm - lm, ht);


            sf.Alignment = StringAlignment.Center;
            float cx = lm + (((rm - lm) * 25) / 100);
            float tx = lm + (((rm - lm) * 12.5f) / 100);
            e.Graphics.DrawLine(new Pen(Brushes.Black), cx, y, cx, y + ht);
            e.Graphics.DrawString("Account Name", cFont, Brushes.Black, tx, y, sf);

            cx += ((rm - lm) * 25) / 100;
            tx = cx - ((rm - lm) * 25) / 200;
            e.Graphics.DrawLine(new Pen(Brushes.Black), cx, y, cx, y + ht);
            e.Graphics.DrawString("Total Charge", cFont, Brushes.Black, tx, y, sf);

            cx += ((rm - lm) * 25) / 100;
            tx = cx - ((rm - lm) * 25) / 200;
            e.Graphics.DrawLine(new Pen(Brushes.Black), cx, y, cx, y + ht);
            e.Graphics.DrawString("Total Payment", cFont, Brushes.Black, tx, y, sf);

            tx += ((rm - lm) * 25) / 100;
            e.Graphics.DrawString("Total Balance", cFont, Brushes.Black, tx, y, sf);

            //Data
            double tC = 0, tP = 0, c, p, b, tB=0;
            

            y += ht * (1.5f);
            y2 += ht * (1.5f);
            ht = cFont.GetHeight(e.Graphics);
            lpp = (bm - y) / ht;
            int cl = 0;
            float stx = 0, stx2 = 0;
            cFont = new Font("Courier New", 11f, FontStyle.Regular);
            while (cl <= lpp && cnt < grdItems.Rows.Count)
            {
                sf.Alignment = StringAlignment.Near;
                stx = lm + 1;
                stx2 = lm + ((rm - lm) * 56) / 100;

                str = grdItems.Rows[cnt].Cells["Account Name"].Value.ToString();
                if (str.Length > 17)
                    str = str.Substring(0, 14) + "...";
                e.Graphics.DrawString(str, cFont, Brushes.Black, stx, y, sf);

                sf.Alignment = StringAlignment.Far;
                stx += ((rm - lm) * 49) / 100;
                
                c = double.Parse(grdItems.Rows[cnt].Cells["Total Charged"].Value.ToString());
                tC += c;
                str = grdItems.Rows[cnt].Cells["Total Charged"].Value.ToString();
                e.Graphics.DrawString(str, cFont, Brushes.Black, stx, y, sf);
                y += ht;

                stx += ((rm - lm) * 25) / 100;
                str = grdItems.Rows[cnt].Cells["Total Payment"].Value.ToString();
                e.Graphics.DrawString(str, cFont, Brushes.Black, stx, y2, sf);
                p = double.Parse(grdItems.Rows[cnt].Cells["Total Payment"].Value.ToString());
                tP += p;

                stx += ((rm - lm) * 25) / 100;
                str = grdItems.Rows[cnt].Cells["Total Balance"].Value.ToString();
                e.Graphics.DrawString(str, cFont, Brushes.Black, stx, y2, sf);
                y2 += ht;
                b = double.Parse(grdItems.Rows[cnt].Cells["Total Balance"].Value.ToString());
                tB += b;

                cnt++;
                cl++;
            }

            if (y2 >= y)
            {
                tmp = y2;
                tmpStx = stx2;
            }
            else
            {
                tmp = y;
                tmpStx = stx;
            }

            tmpStx = lm + ((rm - lm) * 49) / 100; 
            
            if (cnt < grdItems.Rows.Count)
            {
                sf.Alignment = StringAlignment.Far;
                e.Graphics.DrawString(tC.ToString("#,#0.00"), cFont, Brushes.Blue, tmpStx, tmp, sf);
                tmpStx += ((rm - lm) * 25) / 100;
                e.Graphics.DrawString(tP.ToString("#,#0.00"), cFont, Brushes.Blue, tmpStx, tmp, sf);
                tmpStx += ((rm - lm) * 25) / 100;
                e.Graphics.DrawString(tB.ToString("#,#0.00"), cFont, Brushes.Blue, tmpStx, tmp, sf);

                gTC = gTC + tC;
                gTP = gTP + tP;
                gTB = gTB + tB;

                tC = 0;
                tP = 0;
                tB = 0;
                e.HasMorePages = true;
                pageNum++;
                pp++;
            }
            else
            {
                gTC = gTC + tC;
                gTP = gTP + tP;
                gTB = gTB + tB;

                sf.Alignment = StringAlignment.Far;
                e.Graphics.DrawString(tC.ToString("#,#0.00"), cFont, Brushes.Blue, tmpStx, tmp, sf);
                e.Graphics.DrawString(gTC.ToString("#,#0.00"), cFont, Brushes.Red, tmpStx, tmp + ht, sf);
                tmpStx += ((rm - lm) * 25) / 100;
                e.Graphics.DrawString(tP.ToString("#,#0.00"), cFont, Brushes.Blue, tmpStx, tmp, sf);
                e.Graphics.DrawString(gTP.ToString("#,#0.00"), cFont, Brushes.Red, tmpStx, tmp + ht, sf);
                tmpStx += ((rm - lm) * 25) / 100;
                e.Graphics.DrawString(tB.ToString("#,#0.00"), cFont, Brushes.Blue, tmpStx, tmp, sf);
                e.Graphics.DrawString(gTB.ToString("#,#0.00"), cFont, Brushes.Red, tmpStx, tmp + ht, sf);
                
                
                e.HasMorePages = false;
                cnt = 0;
                pp = 1;
            }

        }
        
    }
}
